#include "PlayState.h"

PlayState::PlayState(GameContext& gc)
	: GameState(gc)
	, mLvl1Spawn (100.0f, 500.0f)
	, mLvl2Spawn (100.0f, 1800.0f)
	, mLvl2Entrance (3600.0f, 300.0f, 40.0f)
	, timeCount (0.0f)
{
}

PlayState::~PlayState()
{
}

void PlayState::Load()
{
	mControlMenu.Load("controlmenu.png");
	mControlMenu.SetPosition(100.0f, 125.0f);
	mLevel1Dialogue.Load("dialogue1.png");
	mLevel1Dialogue.SetPosition(225.0f, 500.0f);
	
	
	mCharacter.Load();
	if(mGameContext.GetLevel() == 1)
		mCharacter.SetPosition(mLvl1Spawn);
	else if(mGameContext.GetLevel() == 2)
		mCharacter.SetPosition(mLvl2Spawn);
	
	mEnemyPool.Load(mGameContext.GetLevel());

	char levelName[256];
	char texturePackName[256];
	sprintf_s(levelName, 256, "level0%d.txt", mGameContext.GetLevel());
	sprintf_s(texturePackName, 256, "texturepack0%d.txt", mGameContext.GetLevel());
	mMap.Load(levelName, texturePackName, mGameContext.GetLevel());
}

void PlayState::Unload()
{
	mControlMenu.Unload();
	mLevel1Dialogue.Unload();
	mMap.Unload();
	mCharacter.Unload();
	mEnemyPool.Unload();
}

NextState PlayState::Update(float deltaTime)
{
	mCharacter.Update(deltaTime, mMap, mEnemyPool);
	mMap.Update(deltaTime, mCharacter);
	mControlMenu.Update(deltaTime);
	mLevel1Dialogue.Update(deltaTime);
	mEnemyPool.Update(deltaTime, mMap, mCharacter);
	timeCount += deltaTime;
	
	if(!mCharacter.CharacterAlive())
	{
		if(mGameContext.GetLevel() == 1)
			mCharacter.SetPosition(mLvl1Spawn);
		else if(mGameContext.GetLevel() == 2)
			mCharacter.SetPosition(mLvl2Spawn);
	}

	NextState nextState = None;
	if(Input_IsKeyPressed(Keys::ESCAPE))
		nextState = Frontend;
	if(mCharacter.GameOverStateSwitch())
	{
		Graphics_DebugText("GAME OVER", 300.0f, 300.0f, 0xffffff);
		_sleep(100);
		nextState = Frontend;
	}
	if(mGameContext.GetLevel() == 1)
	{
		if(Level2Entered())
		{
			nextState = Gameplay;
			mGameContext.SetLevel(2);
		}
	}

	return nextState;
}

void PlayState::Render()
{
	/////////////////////REFACTOR///////////////////////////
	//obtain screen center
	const int kWinWidth = IniFile_GetInt("WinWidth", 800);
	const int kWinHeight = IniFile_GetInt("WinHeight", 600);

	//target to be viewed in center of screen space
	//view target's position determines offset to keep world and screen space aligned
	SVector2 viewTarget = mCharacter.GetPosition();
	SVector2 viewOffset;

	//view target subtract half of screen
	//we use negative view target to move the world up and left
	viewOffset.x = viewTarget.x - (kWinWidth * 0.5f);
	viewOffset.y = viewTarget.y - (kWinHeight * 0.5f);

	//add a viewOffset limit so that we don't offset beyond the edge of the map
	SVector2 limit;
	limit.x = (float)mMap.GetWidth() - kWinWidth;
	limit.y = (float)mMap.GetHeight() - kWinHeight;

	//clamp grabs a floating point value,
	//if < minimum becomes minimum, if > maximum, becomes maximum
	viewOffset.x = Clamp(viewOffset.x, 0.0f, limit.x);
	viewOffset.y = Clamp(viewOffset.y, 0.0f, limit.y);
	/////////////////////////////////////////////////////////

	mMap.Render(viewOffset);
	mCharacter.Render(viewOffset);
	mEnemyPool.Render(viewOffset);

	if(Input_IsKeyDown(Keys::H))
		mControlMenu.Render();
	if(mGameContext.GetLevel() == 1)
		if(timeCount < 7.0f)
			mLevel1Dialogue.Render();

}

bool PlayState::Level2Entered()
{
	SVector2 charPos = mCharacter.GetPosition();
	return charPos.y <= 150.0f;
}